package com.younge.spring.component.security;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.younge.spring.repository.dao.SysUser;
import jakarta.annotation.Nonnull;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpHeaders;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;
import java.time.Duration;

@Slf4j
public class JwtValidationFilter extends OncePerRequestFilter {

    private final UserDetailsService userDetailsService;
    private final StringRedisTemplate redis;
    private final ObjectMapper objectMapper;
    Long tokenTtl;

    public JwtValidationFilter(UserDetailsService userDetailsService, Long tokenTtl,
                               StringRedisTemplate redisTemplate, ObjectMapper objectMapper) {
        this.userDetailsService = userDetailsService;
        this.redis = redisTemplate;
        this.tokenTtl = tokenTtl;
        this.objectMapper = objectMapper;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, @Nonnull HttpServletResponse response,
                                    @Nonnull FilterChain chain) throws ServletException, IOException {
        // 获取请求token
        String token = request.getHeader(HttpHeaders.AUTHORIZATION);
        try {
            // 如果请求头中没有Authorization信息，或者Authorization以Bearer开头，则认为是匿名用户
            if (!StringUtils.hasLength(token)) {
                chain.doFilter(request, response);
                return;
            }

            if (token.startsWith("Bearer")) {
                token = token.substring(7);
            }
            log.debug("token: {}", token);
            // 验证token是否有效
            String json = redis.opsForValue().get("token:" + token);
            if (json == null) {
                response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
                return;
            }

            // 解析用户信息 → ThreadLocal
            SysUser user = objectMapper.readValue(json, SysUser.class);
            UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(user,
                    token, null);
            SecurityContextHolder.getContext().setAuthentication(authenticationToken);

            // 刷新过期时间
            redis.expire("token:" + token, Duration.ofMinutes(tokenTtl));

//
//            // 去除 Bearer 前缀
//            token = token.substring(SecurityConstants.JWT_TOKEN_PREFIX.length());
//            // 解析 Token
//            JWT jwt = JWTUtil.parseToken(token);
//
//            // 检查 Token 是否有效(验签 + 是否过期)
//            boolean isValidate = jwt.setKey(secretKey).validate(0);
//            if (!isValidate) {
//                log.error("JwtValidationFilter error: token is invalid");
//                throw new ApiException(ResultCode.UNAUTHORIZED);
//            }
//            JSONObject payloads = jwt.getPayloads();
//            String username = payloads.getStr(JWTPayload.SUBJECT);
//            SysUserDetails userDetails = (SysUserDetails) this.userDetailsService.loadUserByUsername(username);
//
//            UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken
//            (userDetails, null, userDetails.getAuthorities());
//            authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
//            SecurityContextHolder.getContext().setAuthentication(authentication);
//
//        } catch (Exception e) {
//            log.error("JwtValidationFilter error: {}", e.getMessage());
//            SecurityContextHolder.clearContext();
//            throw new ApiException(ResultCode.UNAUTHORIZED);
//        }
            // Token有效或无Token时继续执行过滤链
            chain.doFilter(request, response);
        } catch (Exception e) {
            log.warn("JwtValidationFilter error: {}", e.getLocalizedMessage());
            SecurityContextHolder.clearContext();
            throw new RuntimeException("请求未授权");
        }
    }
}